package com.wang.common.security.interceptor;

import cn.hutool.core.util.StrUtil;
import com.wang.common.security.exception.ServiceException;
import com.wang.common.security.service.TokenService;
import com.wang.common.core.constants.Constant;
import com.wang.common.core.constants.HttpConstants;
import com.wang.common.core.enums.ResultCode;

import com.wang.common.core.utils.ThreadLocalUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
public class TokenInterceptor implements HandlerInterceptor {
    @Autowired
    private TokenService tokenService;

    @Value("${jwt.secret}")
    public String secret; //他的值取决于当前拦截器的Bean被那个模块使用

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //在进入拦截器之后延长token在Redis的剩余时间
        String token = getToken(request);
        //如果为空.不通过校验
        if (StrUtil.isEmpty(token)){
            throw new ServiceException(ResultCode.FAILED_UNAUTHORIZED);
        }
        //延长token时间
        tokenService.extendTokenTime(token,secret);
        //在当前线程中保存当前用户的key和id
        Claims claims = tokenService.getClaims(token,secret);

        Long userId = tokenService.getUserId(token,secret);

        //保存用户id到当前线程中
        ThreadLocalUtil.set(Constant.USER_ID,userId);
        return true; //返回true说明成功拦截
    }
    /**
     * 从请求头中获取请求token
     */
    private String getToken(HttpServletRequest request) {
        String token = request.getHeader(HttpConstants.AUTHENTICATION);
        // 如果前端设置了令牌前缀，则裁剪掉前缀
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        return token;
    }
}